import { _decorator, Component, Game, instantiate, Node, NodePool, SpriteFrame, UITransform, v3 } from 'cc';
import { KugoPiecesType } from '../../KugoConst';
import { KuGoConfig } from '../../KugoConfig';
import { kuModel } from '../../KugoModel';
import { ChessPieces } from './ChessPieces';
import { ChessPoint, DropChessReply, GameState, PiecesType } from '../../proto/proto';
import { kugoControl } from '../../KugoControl';
import { EventMgr } from '../../../../../scripts/GlobalMessage';
import { URLData } from '../../../../../scripts/URLData';
const { ccclass, property } = _decorator;


/**棋子管理 */
@ccclass('ChessPiecesMgr')
export class ChessPiecesMgr extends Component {
    /**棋子 */
    @property(ChessPieces)
    pieces:ChessPieces = null

    @property(SpriteFrame)
    whiteChess:SpriteFrame = null

    @property(SpriteFrame)
    blackChess:SpriteFrame = null

    /**棋子操作标记 */
    @property(Node)
    newFlag:Node = null

    /**被吃棋子标记 */
    @property(Node)
    killFlag:Node = null

    /**棋子移动原点标记 */
    @property(Node)
    startPoint:Node = null

    /**选中标记 */
    @property(Node)
    selectChess:Node = null
    
    /**可移动标记 */
    @property(Node)
    selectPoint:Node = null
    /**单格宽度 */
    private _rowWidth = 0
    /**单格高度 */
    private _colHeight = 0
    private _gridSize = KuGoConfig.GridSize - 1

    private _piecesPool:NodePool = null
    start() {
        this.selectChess.active = false
        this.selectPoint.active = false

        this._piecesPool = new NodePool()
        this._piecesPool.put(this.pieces.node)

        this._selectPointPool = new NodePool()
        this._selectPointPool.put(this.selectPoint)
        
        let cSize = this.node.getComponent(UITransform).contentSize
        this._rowWidth = cSize.width / this._gridSize
        this._colHeight = cSize.height / this._gridSize

        this.newFlag.active = false
        this.startPoint.active = false
        this.killFlag.active = false
    }

    /**获取一个新棋子 */
    getPieces(type:KugoPiecesType){
        let pieces = this._piecesPool.get()
        if (!pieces) {
            pieces = instantiate(this.pieces.node) 
        }
        if (type == KugoPiecesType.WHITE) {
            pieces.getComponent(ChessPieces).setType(type, this.whiteChess)
        }else{
            pieces.getComponent(ChessPieces).setType(type, this.blackChess)
        }
        return pieces
    }

    /**删子 */
    delPieces(node:Node){
        this._piecesPool.put(node)
    }

    private _clickPoints:ChessPoint[] = []
    /**落子 */
    drop(pos:{x:number,y:number}){
        //计算坐标落点
        let dropRow = Math.floor(pos.x/this._rowWidth)
        let dropCol = Math.floor(pos.y/this._colHeight)
        let userInfo = kuModel.UserMgr.getUserById(URLData.userId)
        if (kuModel.ChessBase.CurSeat != userInfo.SeatId) {
            console.error("不该你出手")
            return
        }

        let point:ChessPoint = {
            Row : dropRow,
            Col : dropCol
        }

        if (kuModel.ChessBase.GameState == GameState.Fly || GameState.Jump == kuModel.ChessBase.GameState) {
            let chessData = kuModel.ChessBase.ChessBaseData
            if (chessData[point.Row][point.Col].type != KugoPiecesType.NONE 
                && this._clickPoints.length > 0 ) {
                if (this._clickPoints.length == 1 && chessData[point.Row][point.Col].type == userInfo.PiecesType) {
                    this._clickPoints = [point]
                    this.showSelectFlag()
                }else{
                    console.error("请选择空位置")
                }
                return
            }
            if (this._clickPoints.length == 0 && chessData[point.Row][point.Col].type != userInfo.PiecesType  ) {
                console.error("请选择非空位置")
                return
            }
            for (let index = 0; index < this._clickPoints.length; index++) {
                const p = this._clickPoints[index];
                if (p.Col == point.Col && p.Row == point.Row) {
                    console.error("重复点击")
                    return
                }
            }
            if(GameState.Jump == kuModel.ChessBase.GameState){
                if (this._clickPoints.length ==  0) {
                    this._clickPoints.push(point)
                }else{
                    const pointLast = this._clickPoints[this._clickPoints.length - 1];
                    const pointNext = point;
                    if((pointLast.Col != pointNext.Col && pointLast.Row != pointNext.Row)
                        || (Math.abs(pointLast.Col - pointNext.Col) > 2 || Math.abs(pointLast.Row - pointNext.Row) > 2) ){
                        console.error("此点距离远")
                        return
                    }
                    this._clickPoints.push(point)
                }
            }else{
                this._clickPoints.push(point)
            }
            this.showSelectFlag()
        }else if(kuModel.ChessBase.GameState == GameState.DropPieces){
            if (kuModel.ChessBase.CheckDrop(point)) {
                kugoControl.c2sDropPieces( [point] )
                this._clickPoints = []
            }
        }
        
    }
    
    dropCall(data:DropChessReply){
        this.hideSelectFlag()
        if ( data.Point.length == 1) {
            let point = data.Point[0]
            this.showNewFlag(point)
        }else{
            if (data.KillPoint.length == 0 &&  data.Point.length == 2) {
                let startPoint = data.Point[0]
                let delPieces = kuModel.ChessBase.DelPieces(startPoint)
                this.delPieces(delPieces)

                let endPoint = data.Point[1]
                this.showNewFlag(endPoint)
                
            }
        }
    }

    showNewFlag(point:ChessPoint){
        let chessData = kuModel.ChessBase.ChessBaseData
        if (chessData[point.Row][point.Col].type == KugoPiecesType.NONE) {
            this.newFlag.active = false
            return
        }
        this.newFlag.active = true
        let pos = this.getPos(point)
        this.newFlag.setPosition(pos.x, pos.y)
        this.newFlag.setSiblingIndex(999)
    }

    /**刷新棋盘 */
    refreshChess(){
        let chess = kuModel.ChessBase.ChessBaseData
        for (let row = 0; row < KuGoConfig.GridSize; row++) {
            for (let col = 0; col < KuGoConfig.GridSize; col++) {
                let item = chess[row][col]
                if(item){
                    if (item.type == KugoPiecesType.NONE) {
                        if(item.node){
                            this.delPieces(item.node)
                            item.node = null
                        }
                    }else{
                        if (item.node == null) {
                            let point :ChessPoint = {
                                Row:row,
                                Col:col
                            }
                            let pieces = this.getPieces(item.type)
                            pieces.parent = this.node
                            let pos = this.getPos(point)
                            pieces.setPosition(pos)
                            kuModel.ChessBase.Drop(point, item.type, pieces)
                            pieces.getComponent(ChessPieces).setPoint(point)
                            kuModel.ChessBase.setPieces(point,pieces)
                        }
                    }
                }
            }
        }
    }
    
    opt(eventName){
        if (kuModel.ChessBase.GameState <= GameState.DropPieces || 
            kuModel.ChessBase.GameState == GameState.GameOver ) {
            return            
        }
        switch (eventName) {
            case "BtnConfirm":
                console.log("点击确定落子")
                this.comfrimDropChess()
                break;
            case "BtnCancel":
                console.log("点击撤销")
                this._clickPoints = []
                this.showSelectFlag() 
                break;
            case "BtnBack":
                console.log("点击回退一步")
                if(this._clickPoints.length > 0){
                    this._clickPoints.splice(this._clickPoints.length - 1, 1)
                }
                this.showSelectFlag()    
                break;
            default:
                break;
        }
    }

    getPos(point){
        return  v3(point.Row*this._rowWidth,point.Col*this._colHeight)
    }

    
    private _selectPointPool:NodePool = null 
    private _selectPointArr:Node[] = []
    
    getSelectPointItem(){
        let item = this._selectPointPool.get()
        if(item == null){
            item = instantiate(this.selectPoint)
        }
        this._selectPointArr.push(item)
        item.parent = this.node
        item.active = true
        return item
    }

    clearSelectPointItem(){
        this._selectPointArr.forEach(item=>{
            item.active = false
            this._selectPointPool.put(item)
        })
    }

    hideSelectFlag(){
        this.selectChess.active = false
        this.clearSelectPointItem()
    }

    showSelectFlag(){
        this.hideSelectFlag()
        if (kuModel.ChessBase.GameState == GameState.Jump || 
            kuModel.ChessBase.GameState == GameState.Fly ) {
            let startPoint = this._clickPoints[0]
            this.selectChess.active = true
            let pos = this.getPos(startPoint)
            this.selectChess.setPosition(pos.x + 1, pos.y + 4)

            for (let index = 1; index < this._clickPoints.length; index++) {
                const point = this._clickPoints[index];
                let item = this.getSelectPointItem()
                let pos = this.getPos(point)
                item.setPosition(pos.x, pos.y)
            }
        }
    }

    
    comfrimDropChess(){
        if (this._clickPoints.length < 2) {
            console.log("不合法")
            return 
        }
        for (let index = 0; index < this._clickPoints.length -1; index++) {
            const point = this._clickPoints[index];
            const pointNext = this._clickPoints[index];
            if (GameState.Jump == kuModel.ChessBase.GameState) {
                if((point.Col != pointNext.Col && point.Row != pointNext.Row)
                    || (Math.abs(point.Col - pointNext.Col) > 2 || Math.abs(point.Row - pointNext.Row) > 2) ){
                    console.error("落点选择异常")
                    return
                }
            }
        }
        kugoControl.c2sDropPieces( this._clickPoints )
        this._clickPoints = []
    }
}

